#ifndef INT_W25Q128_H
#define INT_W25Q128_H

#include "main.h"
#include "Dri_SPI.h"

/* W25Q128 命令定义 */
#define W25Q_CMD_WRITE_ENABLE       0x06    // 写使能
#define W25Q_CMD_WRITE_DISABLE      0x04    // 写禁止
#define W25Q_CMD_READ_STATUS_REG1   0x05    // 读状态寄存器1
#define W25Q_CMD_READ_STATUS_REG2   0x35    // 读状态寄存器2
#define W25Q_CMD_WRITE_STATUS_REG   0x01    // 写状态寄存器
#define W25Q_CMD_PAGE_PROGRAM       0x02    // 页编程
#define W25Q_CMD_QUAD_PAGE_PROGRAM  0x32    // 四线页编程
#define W25Q_CMD_BLOCK_ERASE_64K    0xD8    // 64KB块擦除
#define W25Q_CMD_BLOCK_ERASE_32K    0x52    // 32KB块擦除
#define W25Q_CMD_SECTOR_ERASE       0x20    // 4KB扇区擦除
#define W25Q_CMD_CHIP_ERASE         0xC7    // 整片擦除
#define W25Q_CMD_ERASE_SUSPEND      0x75    // 擦除暂停
#define W25Q_CMD_ERASE_RESUME       0x7A    // 擦除恢复
#define W25Q_CMD_POWER_DOWN         0xB9    // 掉电
#define W25Q_CMD_HIGH_PERF_MODE     0xA3    // 高性能模式
#define W25Q_CMD_CNT_READ_MODE_RST  0xFF    // 连续读模式复位
#define W25Q_CMD_RELEASE_POWER_DOWN 0xAB    // 释放掉电/设备ID
#define W25Q_CMD_MANUFACTURER_ID    0x90    // 制造商/设备ID
#define W25Q_CMD_JEDEC_ID           0x9F    // JEDEC ID
#define W25Q_CMD_READ_DATA          0x03    // 读数据
#define W25Q_CMD_FAST_READ          0x0B    // 快速读数据
#define W25Q_CMD_FAST_READ_DUAL_OUT 0x3B    // 双线输出快速读
#define W25Q_CMD_FAST_READ_QUAD_OUT 0x6B    // 四线输出快速读
#define W25Q_CMD_FAST_READ_DUAL_IO  0xBB    // 双线I/O快速读
#define W25Q_CMD_FAST_READ_QUAD_IO  0xEB    // 四线I/O快速读

/* W25Q128 参数定义 */
#define W25Q128_JEDEC_ID            0xEF4018  // W25Q128JV JEDEC ID
#define W25Q128_CAPACITY            (16*1024*1024)  // 16MB
#define W25Q128_SECTOR_SIZE         4096      // 4KB扇区
#define W25Q128_PAGE_SIZE           256       // 256字节页
#define W25Q128_SECTOR_COUNT        4096      // 扇区数量
#define W25Q128_PAGE_COUNT          65536     // 页数量

/* 状态寄存器位定义 */
#define W25Q_SR1_BUSY               0x01      // 忙标志
#define W25Q_SR1_WEL                0x02      // 写使能锁存
#define W25Q_SR1_BP0                0x04      // 块保护位0
#define W25Q_SR1_BP1                0x08      // 块保护位1
#define W25Q_SR1_BP2                0x10      // 块保护位2
#define W25Q_SR1_TB                 0x20      // 顶部/底部保护
#define W25Q_SR1_SEC                0x40      // 扇区保护
#define W25Q_SR1_SRP0               0x80      // 状态寄存器保护0

/* W25Q128 设备结构体 */
typedef struct {
    GPIO_TypeDef* cs_port;      // 片选端口
    uint16_t cs_pin;            // 片选引脚
    uint32_t jedec_id;          // JEDEC ID
    uint32_t capacity;          // 容量(字节)
    uint32_t sector_size;       // 扇区大小
    uint32_t page_size;         // 页大小
    uint8_t initialized;        // 初始化标志
} W25Q_Device_t;

/* W25Q128 逻辑卷结构体(用于多芯片拼接) */
typedef struct {
    W25Q_Device_t* devices[2];  // 设备数组
    uint8_t device_count;       // 设备数量
    uint32_t total_capacity;    // 总容量
} W25Q_Volume_t;

/* 函数声明 */

/**
 * @brief 初始化W25Q128设备
 * @param dev 设备结构体指针
 * @param cs_port 片选端口
 * @param cs_pin 片选引脚
 * @return 0-成功, 其他-失败
 */
int W25Q_Init(W25Q_Device_t* dev, GPIO_TypeDef* cs_port, uint16_t cs_pin);

/**
 * @brief 读取JEDEC ID
 * @param dev 设备结构体指针
 * @param jedec_id JEDEC ID指针
 * @return 0-成功, 其他-失败
 */
int W25Q_ReadJedecID(W25Q_Device_t* dev, uint32_t* jedec_id);

/**
 * @brief 读取状态寄存器1
 * @param dev 设备结构体指针
 * @return 状态寄存器值
 */
uint8_t W25Q_ReadStatusReg1(W25Q_Device_t* dev);

/**
 * @brief 等待设备空闲
 * @param dev 设备结构体指针
 * @param timeout 超时时间(ms)
 * @return 0-成功, 其他-超时
 */
int W25Q_WaitBusy(W25Q_Device_t* dev, uint32_t timeout);

/**
 * @brief 写使能
 * @param dev 设备结构体指针
 */
void W25Q_WriteEnable(W25Q_Device_t* dev);

/**
 * @brief 写禁止
 * @param dev 设备结构体指针
 */
void W25Q_WriteDisable(W25Q_Device_t* dev);

/**
 * @brief 读取数据
 * @param dev 设备结构体指针
 * @param addr 地址
 * @param buffer 数据缓冲区
 * @param size 数据长度
 * @return 0-成功, 其他-失败
 */
int W25Q_ReadData(W25Q_Device_t* dev, uint32_t addr, uint8_t* buffer, uint32_t size);

/**
 * @brief 快速读取数据
 * @param dev 设备结构体指针
 * @param addr 地址
 * @param buffer 数据缓冲区
 * @param size 数据长度
 * @return 0-成功, 其他-失败
 */
int W25Q_FastRead(W25Q_Device_t* dev, uint32_t addr, uint8_t* buffer, uint32_t size);

/**
 * @brief 页编程
 * @param dev 设备结构体指针
 * @param addr 地址
 * @param buffer 数据缓冲区
 * @param size 数据长度(最大256字节)
 * @return 0-成功, 其他-失败
 */
int W25Q_PageProgram(W25Q_Device_t* dev, uint32_t addr, const uint8_t* buffer, uint32_t size);

/**
 * @brief 写入数据(自动处理跨页)
 * @param dev 设备结构体指针
 * @param addr 地址
 * @param buffer 数据缓冲区
 * @param size 数据长度
 * @return 0-成功, 其他-失败
 */
int W25Q_WriteData(W25Q_Device_t* dev, uint32_t addr, const uint8_t* buffer, uint32_t size);

/**
 * @brief 扇区擦除(4KB)
 * @param dev 设备结构体指针
 * @param addr 扇区地址
 * @return 0-成功, 其他-失败
 */
int W25Q_SectorErase(W25Q_Device_t* dev, uint32_t addr);

/**
 * @brief 块擦除(64KB)
 * @param dev 设备结构体指针
 * @param addr 块地址
 * @return 0-成功, 其他-失败
 */
int W25Q_BlockErase(W25Q_Device_t* dev, uint32_t addr);

/**
 * @brief 整片擦除
 * @param dev 设备结构体指针
 * @return 0-成功, 其他-失败
 */
int W25Q_ChipErase(W25Q_Device_t* dev);

/* 逻辑卷操作函数 */

/**
 * @brief 初始化逻辑卷
 * @param volume 逻辑卷结构体指针
 * @param dev1 设备1指针
 * @param dev2 设备2指针
 * @return 0-成功, 其他-失败
 */
int W25Q_VolumeInit(W25Q_Volume_t* volume, W25Q_Device_t* dev1, W25Q_Device_t* dev2);

/**
 * @brief 从逻辑卷读取数据
 * @param volume 逻辑卷结构体指针
 * @param addr 逻辑地址
 * @param buffer 数据缓冲区
 * @param size 数据长度
 * @return 0-成功, 其他-失败
 */
int W25Q_VolumeRead(W25Q_Volume_t* volume, uint32_t addr, uint8_t* buffer, uint32_t size);

/**
 * @brief 向逻辑卷写入数据
 * @param volume 逻辑卷结构体指针
 * @param addr 逻辑地址
 * @param buffer 数据缓冲区
 * @param size 数据长度
 * @return 0-成功, 其他-失败
 */
int W25Q_VolumeWrite(W25Q_Volume_t* volume, uint32_t addr, const uint8_t* buffer, uint32_t size);

/**
 * @brief 逻辑卷扇区擦除
 * @param volume 逻辑卷结构体指针
 * @param addr 逻辑地址
 * @return 0-成功, 其他-失败
 */
int W25Q_VolumeSectorErase(W25Q_Volume_t* volume, uint32_t addr);

#endif
